stream-chat-react-native-core 4.2.0 → 4.3.0-beta.3

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 (97) hide show
  1. package/lib/commonjs/components/Attachment/Giphy.js +57 -26
  2. package/lib/commonjs/components/Attachment/Giphy.js.map +1 -1
  3. package/lib/commonjs/components/Channel/Channel.js +28 -13
  4. package/lib/commonjs/components/Channel/Channel.js.map +1 -1
  5. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js +6 -0
  6. package/lib/commonjs/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  7. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js +1 -1
  8. package/lib/commonjs/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  9. package/lib/commonjs/components/ImageGallery/ImageGallery.js +24 -21
  10. package/lib/commonjs/components/ImageGallery/ImageGallery.js.map +1 -1
  11. package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.js +1 -1
  12. package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.js.map +1 -1
  13. package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.test.js +5 -0
  14. package/lib/commonjs/components/Message/MessageSimple/utils/parseLinks.test.js.map +1 -1
  15. package/lib/commonjs/components/MessageInput/MessageInput.js +50 -173
  16. package/lib/commonjs/components/MessageInput/MessageInput.js.map +1 -1
  17. package/lib/commonjs/components/MessageInput/components/InputEditingStateHeader.js +138 -0
  18. package/lib/commonjs/components/MessageInput/components/InputEditingStateHeader.js.map +1 -0
  19. package/lib/commonjs/components/MessageInput/components/InputGiphySearch.js +179 -0
  20. package/lib/commonjs/components/MessageInput/components/InputGiphySearch.js.map +1 -0
  21. package/lib/commonjs/components/MessageInput/components/InputReplyStateHeader.js +138 -0
  22. package/lib/commonjs/components/MessageInput/components/InputReplyStateHeader.js.map +1 -0
  23. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js +2 -2
  24. package/lib/commonjs/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  25. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +6 -0
  26. package/lib/commonjs/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  27. package/lib/commonjs/contexts/overlayContext/OverlayContext.js +1 -1
  28. package/lib/commonjs/contexts/overlayContext/OverlayContext.js.map +1 -1
  29. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js +15 -12
  30. package/lib/commonjs/contexts/overlayContext/OverlayProvider.js.map +1 -1
  31. package/lib/commonjs/contexts/themeContext/utils/theme.js +8 -2
  32. package/lib/commonjs/contexts/themeContext/utils/theme.js.map +1 -1
  33. package/lib/commonjs/version.json +1 -1
  34. package/lib/module/components/Attachment/Giphy.js +57 -26
  35. package/lib/module/components/Attachment/Giphy.js.map +1 -1
  36. package/lib/module/components/Channel/Channel.js +28 -13
  37. package/lib/module/components/Channel/Channel.js.map +1 -1
  38. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js +6 -0
  39. package/lib/module/components/Channel/hooks/useCreateInputMessageInputContext.js.map +1 -1
  40. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js +1 -1
  41. package/lib/module/components/Channel/hooks/useCreatePaginatedMessageListContext.js.map +1 -1
  42. package/lib/module/components/ImageGallery/ImageGallery.js +24 -21
  43. package/lib/module/components/ImageGallery/ImageGallery.js.map +1 -1
  44. package/lib/module/components/Message/MessageSimple/utils/parseLinks.js +1 -1
  45. package/lib/module/components/Message/MessageSimple/utils/parseLinks.js.map +1 -1
  46. package/lib/module/components/Message/MessageSimple/utils/parseLinks.test.js +5 -0
  47. package/lib/module/components/Message/MessageSimple/utils/parseLinks.test.js.map +1 -1
  48. package/lib/module/components/MessageInput/MessageInput.js +50 -173
  49. package/lib/module/components/MessageInput/MessageInput.js.map +1 -1
  50. package/lib/module/components/MessageInput/components/InputEditingStateHeader.js +138 -0
  51. package/lib/module/components/MessageInput/components/InputEditingStateHeader.js.map +1 -0
  52. package/lib/module/components/MessageInput/components/InputGiphySearch.js +179 -0
  53. package/lib/module/components/MessageInput/components/InputGiphySearch.js.map +1 -0
  54. package/lib/module/components/MessageInput/components/InputReplyStateHeader.js +138 -0
  55. package/lib/module/components/MessageInput/components/InputReplyStateHeader.js.map +1 -0
  56. package/lib/module/contexts/messageInputContext/MessageInputContext.js +2 -2
  57. package/lib/module/contexts/messageInputContext/MessageInputContext.js.map +1 -1
  58. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js +6 -0
  59. package/lib/module/contexts/messageInputContext/hooks/useCreateMessageInputContext.js.map +1 -1
  60. package/lib/module/contexts/overlayContext/OverlayContext.js +1 -1
  61. package/lib/module/contexts/overlayContext/OverlayContext.js.map +1 -1
  62. package/lib/module/contexts/overlayContext/OverlayProvider.js +15 -12
  63. package/lib/module/contexts/overlayContext/OverlayProvider.js.map +1 -1
  64. package/lib/module/contexts/themeContext/utils/theme.js +8 -2
  65. package/lib/module/contexts/themeContext/utils/theme.js.map +1 -1
  66. package/lib/module/version.json +1 -1
  67. package/lib/typescript/components/Attachment/Giphy.d.ts +5 -3
  68. package/lib/typescript/components/Channel/hooks/useCreateInputMessageInputContext.d.ts +1 -1
  69. package/lib/typescript/components/ImageGallery/ImageGallery.d.ts +2 -1
  70. package/lib/typescript/components/MessageInput/MessageInput.d.ts +1 -1
  71. package/lib/typescript/components/MessageInput/components/InputEditingStateHeader.d.ts +10 -0
  72. package/lib/typescript/components/MessageInput/components/InputGiphySearch.d.ts +10 -0
  73. package/lib/typescript/components/MessageInput/components/InputReplyStateHeader.d.ts +10 -0
  74. package/lib/typescript/contexts/messageContext/MessageContext.d.ts +1 -1
  75. package/lib/typescript/contexts/messageInputContext/MessageInputContext.d.ts +7 -1
  76. package/lib/typescript/contexts/messageInputContext/hooks/useCreateMessageInputContext.d.ts +1 -1
  77. package/lib/typescript/contexts/overlayContext/OverlayContext.d.ts +5 -0
  78. package/lib/typescript/contexts/themeContext/utils/theme.d.ts +8 -2
  79. package/package.json +1 -1
  80. package/src/components/Attachment/Giphy.tsx +41 -12
  81. package/src/components/Channel/Channel.tsx +9 -0
  82. package/src/components/Channel/hooks/useCreateInputMessageInputContext.ts +6 -0
  83. package/src/components/Channel/hooks/useCreatePaginatedMessageListContext.ts +1 -1
  84. package/src/components/ImageGallery/ImageGallery.tsx +14 -6
  85. package/src/components/Message/MessageSimple/utils/parseLinks.test.ts +7 -0
  86. package/src/components/Message/MessageSimple/utils/parseLinks.ts +2 -1
  87. package/src/components/MessageInput/MessageInput.tsx +28 -109
  88. package/src/components/MessageInput/__tests__/__snapshots__/MessageInput.test.js.snap +0 -2
  89. package/src/components/MessageInput/components/InputEditingStateHeader.tsx +102 -0
  90. package/src/components/MessageInput/components/InputGiphySearch.tsx +129 -0
  91. package/src/components/MessageInput/components/InputReplyStateHeader.tsx +102 -0
  92. package/src/contexts/messageInputContext/MessageInputContext.tsx +9 -0
  93. package/src/contexts/messageInputContext/hooks/useCreateMessageInputContext.ts +6 -0
  94. package/src/contexts/overlayContext/OverlayContext.tsx +5 -0
  95. package/src/contexts/overlayContext/OverlayProvider.tsx +2 -0
  96. package/src/contexts/themeContext/utils/theme.ts +16 -4
  97. package/src/version.json +1 -1
@@ -1,4 +1,4 @@
1
1
  import type { DefaultStreamChatGenerics } from '../../../types/types';
2
2
  import type { ThreadContextValue } from '../../threadContext/ThreadContext';
3
3
  import type { MessageInputContextValue } from '../MessageInputContext';
4
- export declare const useCreateMessageInputContext: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ additionalTextInputProps, appendText, asyncIds, asyncUploads, AttachButton, autoCompleteSuggestionsLimit, clearEditingState, clearQuotedMessageState, closeAttachmentPicker, CommandsButton, compressImageQuality, cooldownEndsAt, CooldownTimer, doDocUploadRequest, doImageUploadRequest, editing, editMessage, FileUploadPreview, fileUploads, giphyActive, hasCommands, hasFilePicker, hasImagePicker, ImageUploadPreview, imageUploads, initialValue, Input, inputBoxRef, InputButtons, isValidMessage, maxMessageLength, maxNumberOfFiles, mentionAllAppUsersEnabled, mentionAllAppUsersQuery, mentionedUsers, MoreOptionsButton, numberOfLines, numberOfUploads, onChange, onChangeText, onSelectItem, openAttachmentPicker, openCommandsPicker, openFilePicker, openMentionsPicker, pickFile, quotedMessage, removeFile, removeImage, resetInput, selectedPicker, SendButton, sendImageAsync, sending, sendMessage, sendMessageAsync, SendMessageDisallowedIndicator, sendThreadMessageInChannel, setAsyncIds, setAsyncUploads, setFileUploads, setGiphyActive, setImageUploads, setInputBoxRef, setInputRef, setMentionedUsers, setNumberOfUploads, setQuotedMessageState, setSendThreadMessageInChannel, setShowMoreOptions, setText, showMoreOptions, ShowThreadMessageInChannelButton, text, thread, toggleAttachmentPicker, triggerSettings, updateMessage, uploadFile, uploadImage, uploadNewFile, uploadNewImage, UploadProgressIndicator, }: import("../MessageInputContext").LocalMessageInputContext<StreamChatGenerics> & Omit<import("../MessageInputContext").InputMessageInputContextValue<StreamChatGenerics>, "sendMessage"> & Pick<ThreadContextValue<StreamChatGenerics>, "thread">) => MessageInputContextValue<StreamChatGenerics>;
4
+ export declare const useCreateMessageInputContext: <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>({ additionalTextInputProps, appendText, asyncIds, asyncUploads, AttachButton, autoCompleteSuggestionsLimit, clearEditingState, clearQuotedMessageState, closeAttachmentPicker, CommandsButton, compressImageQuality, cooldownEndsAt, CooldownTimer, doDocUploadRequest, doImageUploadRequest, editing, editMessage, FileUploadPreview, fileUploads, giphyActive, hasCommands, hasFilePicker, hasImagePicker, ImageUploadPreview, imageUploads, initialValue, Input, inputBoxRef, InputButtons, InputEditingStateHeader, InputGiphySearch, InputReplyStateHeader, isValidMessage, maxMessageLength, maxNumberOfFiles, mentionAllAppUsersEnabled, mentionAllAppUsersQuery, mentionedUsers, MoreOptionsButton, numberOfLines, numberOfUploads, onChange, onChangeText, onSelectItem, openAttachmentPicker, openCommandsPicker, openFilePicker, openMentionsPicker, pickFile, quotedMessage, removeFile, removeImage, resetInput, selectedPicker, SendButton, sendImageAsync, sending, sendMessage, sendMessageAsync, SendMessageDisallowedIndicator, sendThreadMessageInChannel, setAsyncIds, setAsyncUploads, setFileUploads, setGiphyActive, setImageUploads, setInputBoxRef, setInputRef, setMentionedUsers, setNumberOfUploads, setQuotedMessageState, setSendThreadMessageInChannel, setShowMoreOptions, setText, showMoreOptions, ShowThreadMessageInChannelButton, text, thread, toggleAttachmentPicker, triggerSettings, updateMessage, uploadFile, uploadImage, uploadNewFile, uploadNewImage, UploadProgressIndicator, }: import("../MessageInputContext").LocalMessageInputContext<StreamChatGenerics> & Omit<import("../MessageInputContext").InputMessageInputContextValue<StreamChatGenerics>, "sendMessage"> & Pick<ThreadContextValue<StreamChatGenerics>, "thread">) => MessageInputContextValue<StreamChatGenerics>;
@@ -1,5 +1,6 @@
1
1
  import React from 'react';
2
2
  import type { BottomSheetMethods } from '@gorhom/bottom-sheet/lib/typescript/types';
3
+ import type { Attachment } from 'stream-chat';
3
4
  import type { AttachmentPickerProps } from '../../components/AttachmentPicker/AttachmentPicker';
4
5
  import type { ImageGalleryCustomComponents } from '../../components/ImageGallery/ImageGallery';
5
6
  import type { MessageType } from '../../components/MessageList/hooks/useMessageList';
@@ -18,6 +19,10 @@ export declare type OverlayContextValue = {
18
19
  };
19
20
  export declare const OverlayContext: React.Context<OverlayContextValue>;
20
21
  export declare type OverlayProviderProps<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics> = Partial<AttachmentPickerProps> & Partial<Pick<AttachmentPickerContextValue, 'attachmentPickerBottomSheetHeight' | 'attachmentSelectionBarHeight' | 'bottomInset' | 'CameraSelectorIcon' | 'FileSelectorIcon' | 'ImageSelectorIcon' | 'topInset'>> & ImageGalleryCustomComponents<StreamChatGenerics> & Partial<Pick<MessageOverlayContextValue<StreamChatGenerics>, 'MessageActionList' | 'MessageActionListItem' | 'OverlayReactionList' | 'OverlayReactions' | 'OverlayReactionsAvatar'>> & Pick<OverlayContextValue, 'translucentStatusBar'> & {
22
+ /**
23
+ * The giphy version to render - check the keys of the [Image Object](https://developers.giphy.com/docs/api/schema#image-object) for possible values. Uses 'fixed_height' by default
24
+ * */
25
+ giphyVersion: keyof NonNullable<Attachment['giphy']>;
21
26
  closePicker?: (ref: React.RefObject<BottomSheetMethods>) => void;
22
27
  error?: boolean | Error;
23
28
  /** https://github.com/GetStream/stream-chat-react-native/wiki/Internationalization-(i18n) */
@@ -229,6 +229,10 @@ export declare type Theme = {
229
229
  editingBoxContainer: ViewStyle;
230
230
  editingBoxHeader: ViewStyle;
231
231
  editingBoxHeaderTitle: TextStyle;
232
+ editingStateHeader: {
233
+ editingBoxHeader: ViewStyle;
234
+ editingBoxHeaderTitle: TextStyle;
235
+ };
232
236
  fileUploadPreview: {
233
237
  dismiss: ViewStyle;
234
238
  fileContainer: ViewStyle;
@@ -238,8 +242,10 @@ export declare type Theme = {
238
242
  fileTextContainer: ViewStyle;
239
243
  flatList: ViewStyle;
240
244
  };
241
- giphyContainer: ViewStyle;
242
- giphyText: TextStyle;
245
+ giphyCommandInput: {
246
+ giphyContainer: ViewStyle;
247
+ giphyText: TextStyle;
248
+ };
243
249
  imageUploadPreview: {
244
250
  dismiss: ViewStyle;
245
251
  flatList: ViewStyle;
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "stream-chat-react-native-core",
3
3
  "description": "The official React Native and Expo components for Stream Chat, a service for building chat applications",
4
- "version": "4.2.0",
4
+ "version": "4.3.0-beta.3",
5
5
  "author": {
6
6
  "company": "Stream.io Inc",
7
7
  "name": "Stream.io Inc"
@@ -3,6 +3,10 @@ import { Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3
3
 
4
4
  import type { Attachment } from 'stream-chat';
5
5
 
6
+ import {
7
+ ImageGalleryContextValue,
8
+ useImageGalleryContext,
9
+ } from '../../contexts/imageGalleryContext/ImageGalleryContext';
6
10
  import {
7
11
  MessageContextValue,
8
12
  useMessageContext,
@@ -11,6 +15,10 @@ import {
11
15
  MessagesContextValue,
12
16
  useMessagesContext,
13
17
  } from '../../contexts/messagesContext/MessagesContext';
18
+ import {
19
+ OverlayContextValue,
20
+ useOverlayContext,
21
+ } from '../../contexts/overlayContext/OverlayContext';
14
22
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
15
23
  import { GiphyIcon } from '../../icons';
16
24
  import { Lightning } from '../../icons/Lightning';
@@ -107,13 +115,20 @@ const styles = StyleSheet.create({
107
115
 
108
116
  export type GiphyPropsWithContext<
109
117
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
110
- > = Pick<
111
- MessageContextValue<StreamChatGenerics>,
112
- 'handleAction' | 'isMyMessage' | 'onLongPress' | 'onPress' | 'onPressIn' | 'preventPress'
113
- > &
118
+ > = Pick<ImageGalleryContextValue<StreamChatGenerics>, 'setImage' | 'setImages'> &
119
+ Pick<
120
+ MessageContextValue<StreamChatGenerics>,
121
+ | 'handleAction'
122
+ | 'isMyMessage'
123
+ | 'message'
124
+ | 'onLongPress'
125
+ | 'onPress'
126
+ | 'onPressIn'
127
+ | 'preventPress'
128
+ > &
114
129
  Pick<MessagesContextValue<StreamChatGenerics>, 'giphyVersion' | 'additionalTouchableProps'> & {
115
130
  attachment: Attachment<StreamChatGenerics>;
116
- };
131
+ } & Pick<OverlayContextValue, 'setOverlay'>;
117
132
 
118
133
  const GiphyWithContext = <
119
134
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -123,12 +138,17 @@ const GiphyWithContext = <
123
138
  const {
124
139
  additionalTouchableProps,
125
140
  attachment,
141
+ giphyVersion,
126
142
  handleAction,
127
143
  isMyMessage,
144
+ message,
128
145
  onLongPress,
129
146
  onPress,
130
147
  onPressIn,
131
148
  preventPress,
149
+ setImage,
150
+ setImages,
151
+ setOverlay,
132
152
  } = props;
133
153
 
134
154
  const { actions, giphy: giphyData, image_url, thumb_url, title, type } = attachment;
@@ -159,8 +179,14 @@ const GiphyWithContext = <
159
179
  let uri = image_url || thumb_url;
160
180
  const giphyDimensions: { height?: number; width?: number } = {};
161
181
 
182
+ const defaultOnPress = () => {
183
+ setImages([message]);
184
+ setImage({ messageId: message.id, url: uri });
185
+ setOverlay('gallery');
186
+ };
187
+
162
188
  if (type === 'giphy' && giphyData) {
163
- const giphyVersionInfo = giphyData[props.giphyVersion];
189
+ const giphyVersionInfo = giphyData[giphyVersion];
164
190
  uri = giphyVersionInfo.url;
165
191
  giphyDimensions.height = parseFloat(giphyVersionInfo.height);
166
192
  giphyDimensions.width = parseFloat(giphyVersionInfo.width);
@@ -247,6 +273,7 @@ const GiphyWithContext = <
247
273
  onPress={(event) => {
248
274
  if (onPress) {
249
275
  onPress({
276
+ defaultHandler: defaultOnPress,
250
277
  emitter: 'giphy',
251
278
  event,
252
279
  });
@@ -337,10 +364,7 @@ const MemoizedGiphy = React.memo(GiphyWithContext, areEqual) as typeof GiphyWith
337
364
 
338
365
  export type GiphyProps<
339
366
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
340
- > = Partial<
341
- Pick<MessageContextValue<StreamChatGenerics>, 'isMyMessage' | 'onLongPress' | 'onPressIn'> &
342
- Pick<MessagesContextValue<StreamChatGenerics>, 'giphyVersion' | 'additionalTouchableProps'>
343
- > & {
367
+ > = Partial<GiphyPropsWithContext<StreamChatGenerics>> & {
344
368
  attachment: Attachment<StreamChatGenerics>;
345
369
  };
346
370
 
@@ -352,10 +376,11 @@ export const Giphy = <
352
376
  >(
353
377
  props: GiphyProps<StreamChatGenerics>,
354
378
  ) => {
355
- const { handleAction, isMyMessage, onLongPress, onPress, onPressIn, preventPress } =
379
+ const { handleAction, isMyMessage, message, onLongPress, onPress, onPressIn, preventPress } =
356
380
  useMessageContext<StreamChatGenerics>();
357
381
  const { additionalTouchableProps, giphyVersion } = useMessagesContext<StreamChatGenerics>();
358
-
382
+ const { setImage, setImages } = useImageGalleryContext<StreamChatGenerics>();
383
+ const { setOverlay } = useOverlayContext();
359
384
  return (
360
385
  <MemoizedGiphy
361
386
  {...{
@@ -363,10 +388,14 @@ export const Giphy = <
363
388
  giphyVersion,
364
389
  handleAction,
365
390
  isMyMessage,
391
+ message,
366
392
  onLongPress,
367
393
  onPress,
368
394
  onPressIn,
369
395
  preventPress,
396
+ setImage,
397
+ setImages,
398
+ setOverlay,
370
399
  }}
371
400
  {...props}
372
401
  />
@@ -105,6 +105,9 @@ import { MessageStatus as MessageStatusDefault } from '../Message/MessageSimple/
105
105
  import { ReactionList as ReactionListDefault } from '../Message/MessageSimple/ReactionList';
106
106
  import { AttachButton as AttachButtonDefault } from '../MessageInput/AttachButton';
107
107
  import { CommandsButton as CommandsButtonDefault } from '../MessageInput/CommandsButton';
108
+ import { InputEditingStateHeader as InputEditingStateHeaderDefault } from '../MessageInput/components/InputEditingStateHeader';
109
+ import { InputGiphySearch as InputGiphyCommandInputDefault } from '../MessageInput/components/InputGiphySearch';
110
+ import { InputReplyStateHeader as InputReplyStateHeaderDefault } from '../MessageInput/components/InputReplyStateHeader';
108
111
  import { CooldownTimer as CooldownTimerDefault } from '../MessageInput/CooldownTimer';
109
112
  import { FileUploadPreview as FileUploadPreviewDefault } from '../MessageInput/FileUploadPreview';
110
113
  import { ImageUploadPreview as ImageUploadPreviewDefault } from '../MessageInput/ImageUploadPreview';
@@ -452,6 +455,9 @@ const ChannelWithContext = <
452
455
  InlineUnreadIndicator = InlineUnreadIndicatorDefault,
453
456
  Input,
454
457
  InputButtons = InputButtonsDefault,
458
+ InputEditingStateHeader = InputEditingStateHeaderDefault,
459
+ InputGiphySearch = InputGiphyCommandInputDefault,
460
+ InputReplyStateHeader = InputReplyStateHeaderDefault,
455
461
  keyboardBehavior,
456
462
  KeyboardCompatibleView = KeyboardCompatibleViewDefault,
457
463
  keyboardVerticalOffset,
@@ -1621,6 +1627,9 @@ const ChannelWithContext = <
1621
1627
  initialValue,
1622
1628
  Input,
1623
1629
  InputButtons,
1630
+ InputEditingStateHeader,
1631
+ InputGiphySearch,
1632
+ InputReplyStateHeader,
1624
1633
  maxMessageLength: maxMessageLengthProp ?? clientChannelConfig?.max_message_length ?? undefined,
1625
1634
  maxNumberOfFiles,
1626
1635
  mentionAllAppUsersEnabled,
@@ -28,6 +28,9 @@ export const useCreateInputMessageInputContext = <
28
28
  initialValue,
29
29
  Input,
30
30
  InputButtons,
31
+ InputEditingStateHeader,
32
+ InputGiphySearch,
33
+ InputReplyStateHeader,
31
34
  maxMessageLength,
32
35
  maxNumberOfFiles,
33
36
  mentionAllAppUsersEnabled,
@@ -80,6 +83,9 @@ export const useCreateInputMessageInputContext = <
80
83
  initialValue,
81
84
  Input,
82
85
  InputButtons,
86
+ InputEditingStateHeader,
87
+ InputGiphySearch,
88
+ InputReplyStateHeader,
83
89
  maxMessageLength,
84
90
  maxNumberOfFiles,
85
91
  mentionAllAppUsersEnabled,
@@ -23,7 +23,7 @@ export const useCreatePaginatedMessageListContext = <
23
23
  ({ deleted_at, latest_reactions, reply_count, status, updated_at }) =>
24
24
  `${deleted_at}${
25
25
  latest_reactions ? latest_reactions.map(({ type }) => type).join() : ''
26
- }${reply_count}${status}${updated_at.toISOString()}`,
26
+ }${reply_count}${status}${updated_at?.toISOString?.() || updated_at}`,
27
27
  )
28
28
  .join();
29
29
 
@@ -53,7 +53,10 @@ import {
53
53
  } from './components/ImageGridHandle';
54
54
 
55
55
  import { useImageGalleryContext } from '../../contexts/imageGalleryContext/ImageGalleryContext';
56
- import { useOverlayContext } from '../../contexts/overlayContext/OverlayContext';
56
+ import {
57
+ OverlayProviderProps,
58
+ useOverlayContext,
59
+ } from '../../contexts/overlayContext/OverlayContext';
57
60
  import { useTheme } from '../../contexts/themeContext/ThemeContext';
58
61
  import { triggerHaptic } from '../../native';
59
62
  import type { DefaultStreamChatGenerics } from '../../types/types';
@@ -130,7 +133,7 @@ type Props<StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamC
130
133
  */
131
134
  imageGalleryGridSnapPoints?: [string | number, string | number];
132
135
  numberOfImageGalleryGridColumns?: number;
133
- };
136
+ } & Pick<OverlayProviderProps<StreamChatGenerics>, 'giphyVersion'>;
134
137
 
135
138
  export const ImageGallery = <
136
139
  StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
@@ -138,6 +141,7 @@ export const ImageGallery = <
138
141
  props: Props<StreamChatGenerics>,
139
142
  ) => {
140
143
  const {
144
+ giphyVersion,
141
145
  imageGalleryCustomComponents,
142
146
  imageGalleryGridHandleHeight,
143
147
  imageGalleryGridSnapPoints,
@@ -308,10 +312,14 @@ export const ImageGallery = <
308
312
  const attachmentImages =
309
313
  cur.attachments?.filter(
310
314
  (attachment) =>
311
- attachment.type === 'image' &&
312
- !attachment.title_link &&
313
- !attachment.og_scrape_url &&
314
- getUrlOfImageAttachment(attachment),
315
+ (attachment.type === 'giphy' &&
316
+ (attachment.giphy?.[giphyVersion]?.url ||
317
+ attachment.thumb_url ||
318
+ attachment.image_url)) ||
319
+ (attachment.type === 'image' &&
320
+ !attachment.title_link &&
321
+ !attachment.og_scrape_url &&
322
+ getUrlOfImageAttachment(attachment)),
315
323
  ) || [];
316
324
 
317
325
  const attachmentPhotos = attachmentImages.map((a) => {
@@ -97,4 +97,11 @@ getstream.io
97
97
  scheme: 'https://',
98
98
  });
99
99
  });
100
+
101
+ it('does not parse a decimal number as a URL', () => {
102
+ const input = '123.456';
103
+ const result = parseLinksFromText(input);
104
+
105
+ expect(result).toHaveLength(0);
106
+ });
100
107
  });
@@ -8,7 +8,8 @@
8
8
  * */
9
9
  const emailUserName = '[\\w+\\.~$_-]+';
10
10
  const schema = `(\\w{2,15}:\\/\\/)`;
11
- const domain = `((?:\\w+\\.\\w+)+(?:[^:\\/\\s]+))`;
11
+ // something.tld OR 123.123.123.123
12
+ const domain = `((?:\\w+\\.[a-zA-Z]+)+(?:[^:\\/\\s]+)|(?:\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}))`;
12
13
  const port = `(:[0-9]{1,5})`;
13
14
  const path = `((?:\\/)?[^?#\\s]+)`;
14
15
  const queryString = `(\\?[^#\\s]+)`;
@@ -1,5 +1,5 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
2
+ import { StyleSheet, View } from 'react-native';
3
3
 
4
4
  import type { UserResponse } from 'stream-chat';
5
5
 
@@ -29,7 +29,6 @@ import {
29
29
  TranslationContextValue,
30
30
  useTranslationContext,
31
31
  } from '../../contexts/translationContext/TranslationContext';
32
- import { CircleClose, CurveLineLeftUp, Edit, Lightning } from '../../icons';
33
32
 
34
33
  import type { Asset } from '../../native';
35
34
  import type { DefaultStreamChatGenerics } from '../../types/types';
@@ -44,6 +43,8 @@ const styles = StyleSheet.create({
44
43
  autoCompleteInputContainer: {
45
44
  alignItems: 'center',
46
45
  flexDirection: 'row',
46
+ paddingLeft: 16,
47
+ paddingRight: 16,
47
48
  },
48
49
  composerContainer: {
49
50
  alignItems: 'flex-end',
@@ -53,28 +54,6 @@ const styles = StyleSheet.create({
53
54
  borderTopWidth: 1,
54
55
  padding: 10,
55
56
  },
56
- editingBoxHeader: {
57
- alignItems: 'center',
58
- flexDirection: 'row',
59
- justifyContent: 'space-between',
60
- paddingBottom: 10,
61
- },
62
- editingBoxHeaderTitle: {
63
- fontSize: 14,
64
- fontWeight: 'bold',
65
- },
66
- giphyContainer: {
67
- alignItems: 'center',
68
- borderRadius: 12,
69
- flexDirection: 'row',
70
- height: 24,
71
- marginRight: 8,
72
- paddingHorizontal: 8,
73
- },
74
- giphyText: {
75
- fontSize: 12,
76
- fontWeight: 'bold',
77
- },
78
57
  inputBoxContainer: {
79
58
  borderRadius: 20,
80
59
  borderWidth: 1,
@@ -120,6 +99,9 @@ type MessageInputPropsWithContext<
120
99
  | 'Input'
121
100
  | 'inputBoxRef'
122
101
  | 'InputButtons'
102
+ | 'InputEditingStateHeader'
103
+ | 'InputGiphySearch'
104
+ | 'InputReplyStateHeader'
123
105
  | 'isValidMessage'
124
106
  | 'maxNumberOfFiles'
125
107
  | 'mentionedUsers'
@@ -160,8 +142,6 @@ const MessageInputWithContext = <
160
142
  asyncIds,
161
143
  asyncUploads,
162
144
  AutoCompleteSuggestionList,
163
- clearEditingState,
164
- clearQuotedMessageState,
165
145
  closeAttachmentPicker,
166
146
  cooldownEndsAt,
167
147
  CooldownTimer,
@@ -175,6 +155,9 @@ const MessageInputWithContext = <
175
155
  Input,
176
156
  inputBoxRef,
177
157
  InputButtons,
158
+ InputEditingStateHeader,
159
+ InputGiphySearch,
160
+ InputReplyStateHeader,
178
161
  isValidMessage,
179
162
  maxNumberOfFiles,
180
163
  members,
@@ -187,11 +170,8 @@ const MessageInputWithContext = <
187
170
  SendButton,
188
171
  sending,
189
172
  sendMessageAsync,
190
- setGiphyActive,
191
- setShowMoreOptions,
192
173
  ShowThreadMessageInChannelButton,
193
174
  suggestions,
194
- t,
195
175
  thread,
196
176
  threadList,
197
177
  triggerType,
@@ -203,25 +183,12 @@ const MessageInputWithContext = <
203
183
 
204
184
  const {
205
185
  theme: {
206
- colors: {
207
- accent_blue,
208
- black,
209
- border,
210
- grey,
211
- grey_gainsboro,
212
- grey_whisper,
213
- white,
214
- white_smoke,
215
- },
186
+ colors: { border, grey_whisper, white, white_smoke },
216
187
  messageInput: {
217
188
  attachmentSelectionBar,
218
189
  autoCompleteInputContainer,
219
190
  composerContainer,
220
191
  container,
221
- editingBoxHeader,
222
- editingBoxHeaderTitle,
223
- giphyContainer,
224
- giphyText,
225
192
  inputBoxContainer,
226
193
  optionsContainer,
227
194
  replyContainer,
@@ -434,33 +401,8 @@ const MessageInputWithContext = <
434
401
  }) => setHeight(newHeight)}
435
402
  style={[styles.container, { backgroundColor: white, borderColor: border }, container]}
436
403
  >
437
- {(editing || quotedMessage) && (
438
- <View style={[styles.editingBoxHeader, editingBoxHeader]}>
439
- {editing ? (
440
- <Edit pathFill={grey_gainsboro} />
441
- ) : (
442
- <CurveLineLeftUp pathFill={grey_gainsboro} />
443
- )}
444
- <Text style={[styles.editingBoxHeaderTitle, { color: black }, editingBoxHeaderTitle]}>
445
- {editing ? t('Editing Message') : t('Reply to Message')}
446
- </Text>
447
- <TouchableOpacity
448
- disabled={disabled}
449
- onPress={() => {
450
- resetInput();
451
- if (editing) {
452
- clearEditingState();
453
- }
454
- if (quotedMessage) {
455
- clearQuotedMessageState();
456
- }
457
- }}
458
- testID='close-button'
459
- >
460
- <CircleClose pathFill={grey} />
461
- </TouchableOpacity>
462
- </View>
463
- )}
404
+ {editing && <InputEditingStateHeader />}
405
+ {quotedMessage && <InputReplyStateHeader />}
464
406
  <View style={[styles.composerContainer, composerContainer]}>
465
407
  {Input ? (
466
408
  <Input
@@ -500,45 +442,16 @@ const MessageInputWithContext = <
500
442
  />
501
443
  ) : null}
502
444
  {fileUploads.length ? <FileUploadPreview /> : null}
503
- <View
504
- style={[
505
- styles.autoCompleteInputContainer,
506
- {
507
- paddingLeft: giphyActive ? 8 : 16,
508
- paddingRight: giphyActive ? 10 : 16,
509
- },
510
- autoCompleteInputContainer,
511
- ]}
512
- >
513
- {giphyActive && (
514
- <View
515
- style={[
516
- styles.giphyContainer,
517
- { backgroundColor: accent_blue },
518
- giphyContainer,
519
- ]}
520
- >
521
- <Lightning height={16} pathFill={white} width={16} />
522
- <Text style={[styles.giphyText, { color: white }, giphyText]}>GIPHY</Text>
523
- </View>
524
- )}
525
- <AutoCompleteInput<StreamChatGenerics>
526
- additionalTextInputProps={additionalTextInputProps}
527
- cooldownActive={!!cooldownRemainingSeconds}
528
- />
529
- {giphyActive && (
530
- <TouchableOpacity
531
- disabled={disabled}
532
- onPress={() => {
533
- setGiphyActive(false);
534
- setShowMoreOptions(true);
535
- }}
536
- testID='close-button'
537
- >
538
- <CircleClose height={20} pathFill={grey} width={20} />
539
- </TouchableOpacity>
540
- )}
541
- </View>
445
+ {giphyActive ? (
446
+ <InputGiphySearch />
447
+ ) : (
448
+ <View style={[styles.autoCompleteInputContainer, autoCompleteInputContainer]}>
449
+ <AutoCompleteInput<StreamChatGenerics>
450
+ additionalTextInputProps={additionalTextInputProps}
451
+ cooldownActive={!!cooldownRemainingSeconds}
452
+ />
453
+ </View>
454
+ )}
542
455
  </View>
543
456
  <View style={[styles.sendButtonContainer, sendButtonContainer]}>
544
457
  {cooldownRemainingSeconds ? (
@@ -745,6 +658,9 @@ export const MessageInput = <
745
658
  Input,
746
659
  inputBoxRef,
747
660
  InputButtons,
661
+ InputEditingStateHeader,
662
+ InputGiphySearch,
663
+ InputReplyStateHeader,
748
664
  isValidMessage,
749
665
  maxNumberOfFiles,
750
666
  mentionedUsers,
@@ -805,6 +721,9 @@ export const MessageInput = <
805
721
  Input,
806
722
  inputBoxRef,
807
723
  InputButtons,
724
+ InputEditingStateHeader,
725
+ InputGiphySearch,
726
+ InputReplyStateHeader,
808
727
  isValidMessage,
809
728
  maxNumberOfFiles,
810
729
  members,
@@ -257,8 +257,6 @@ Array [
257
257
  Object {
258
258
  "alignItems": "center",
259
259
  "flexDirection": "row",
260
- },
261
- Object {
262
260
  "paddingLeft": 16,
263
261
  "paddingRight": 16,
264
262
  },
@@ -0,0 +1,102 @@
1
+ import React from 'react';
2
+ import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
3
+
4
+ import type { ChannelContextValue } from '../../../contexts/channelContext/ChannelContext';
5
+ import {
6
+ MessageInputContextValue,
7
+ useMessageInputContext,
8
+ } from '../../../contexts/messageInputContext/MessageInputContext';
9
+ import { useTheme } from '../../../contexts/themeContext/ThemeContext';
10
+ import { useTranslationContext } from '../../../contexts/translationContext/TranslationContext';
11
+
12
+ import { CircleClose, Edit } from '../../../icons';
13
+ import type { DefaultStreamChatGenerics } from '../../../types/types';
14
+
15
+ const styles = StyleSheet.create({
16
+ editingBoxHeader: {
17
+ alignItems: 'center',
18
+ flexDirection: 'row',
19
+ justifyContent: 'space-between',
20
+ paddingBottom: 10,
21
+ },
22
+ editingBoxHeaderTitle: {
23
+ fontSize: 14,
24
+ fontWeight: 'bold',
25
+ },
26
+ });
27
+
28
+ export type InputEditingStateHeaderPropsWithContext<
29
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
30
+ > = Pick<MessageInputContextValue<StreamChatGenerics>, 'clearEditingState' | 'resetInput'> &
31
+ Pick<ChannelContextValue<StreamChatGenerics>, 'disabled'>;
32
+
33
+ export const InputEditingStateHeaderWithContext = <
34
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
35
+ >({
36
+ clearEditingState,
37
+ disabled,
38
+ resetInput,
39
+ }: InputEditingStateHeaderPropsWithContext<StreamChatGenerics>) => {
40
+ const { t } = useTranslationContext();
41
+ const {
42
+ theme: {
43
+ colors: { black, grey, grey_gainsboro },
44
+ messageInput: {
45
+ editingStateHeader: { editingBoxHeader, editingBoxHeaderTitle },
46
+ },
47
+ },
48
+ } = useTheme();
49
+
50
+ return (
51
+ <View style={[styles.editingBoxHeader, editingBoxHeader]}>
52
+ <Edit pathFill={grey_gainsboro} />
53
+ <Text style={[styles.editingBoxHeaderTitle, { color: black }, editingBoxHeaderTitle]}>
54
+ {t('Editing Message')}
55
+ </Text>
56
+ <TouchableOpacity
57
+ disabled={disabled}
58
+ onPress={() => {
59
+ resetInput();
60
+ clearEditingState();
61
+ }}
62
+ testID='close-button'
63
+ >
64
+ <CircleClose pathFill={grey} />
65
+ </TouchableOpacity>
66
+ </View>
67
+ );
68
+ };
69
+
70
+ const areEqual = <StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics>(
71
+ prevProps: InputEditingStateHeaderPropsWithContext<StreamChatGenerics>,
72
+ nextProps: InputEditingStateHeaderPropsWithContext<StreamChatGenerics>,
73
+ ) => {
74
+ const { disabled: prevDisabled } = prevProps;
75
+ const { disabled: nextDisabled } = nextProps;
76
+
77
+ const disabledEqual = prevDisabled === nextDisabled;
78
+ if (!disabledEqual) return false;
79
+
80
+ return true;
81
+ };
82
+
83
+ const MemoizedInputEditingStateHeader = React.memo(
84
+ InputEditingStateHeaderWithContext,
85
+ areEqual,
86
+ ) as typeof InputEditingStateHeaderWithContext;
87
+
88
+ export type InputEditingStateHeaderProps<
89
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
90
+ > = Partial<InputEditingStateHeaderPropsWithContext<StreamChatGenerics>>;
91
+
92
+ export const InputEditingStateHeader = <
93
+ StreamChatGenerics extends DefaultStreamChatGenerics = DefaultStreamChatGenerics,
94
+ >(
95
+ props: InputEditingStateHeaderProps<StreamChatGenerics>,
96
+ ) => {
97
+ const { clearEditingState, resetInput } = useMessageInputContext<StreamChatGenerics>();
98
+
99
+ return <MemoizedInputEditingStateHeader {...{ clearEditingState, resetInput }} {...props} />;
100
+ };
101
+
102
+ InputEditingStateHeader.displayName = 'EditingStateHeader{messageInput}';